﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using ProyectoBastanteo.Persistencia;
using ProyectoBastanteo.Dominio;

namespace ProyectoBastanteo.Prueba
{
    [TestFixture] 
    public class ClienteDAOPrueba
    {
        
        TipoempresaDAO tipoEmpresaDAO = null;
        ClienteDAO clienteDAO = null;
        RepresentanteDAO RepDAO = null;
        TipoEmpresa tipoEmpresa = null;
        Cliente clienteCreado = null;

        [TestFixtureSetUp]
        public void InicializarPruebas()
        {
            tipoEmpresaDAO = new TipoempresaDAO(); // Instanciamos la implementación elegida (ADO o NHibernate)
            clienteDAO = new ClienteDAO(); // Instanciamos la implementación elegida (ADO o NHibernate)
            RepDAO = new RepresentanteDAO();
            foreach (Representante Represen in RepDAO.ListarTodos())
                RepDAO.Eliminar(Represen);

            foreach (Cliente cliente in clienteDAO.ListarTodos())
                clienteDAO.Eliminar(cliente);
            

            tipoEmpresa = tipoEmpresaDAO.Crear(new TipoEmpresa() { Abreviacion = "SAC" });
        }

        
        [Test]
        public void Test1_Crear()
        {
            // 1. Validar que ocurra un error al intentar crear un cliente con un dato nulo
            Cliente clienteACrear = new Cliente();
            clienteACrear.rucclie = "12345678901";
            clienteACrear.razclie = "PeruBank";
            clienteACrear.fecini = DateTime.Now;            
            clienteACrear.nroempl = 100;
            Assert.Catch<Exception>(delegate
            {
                clienteCreado = clienteDAO.Crear(clienteACrear);
            });
            // 2. Validar que se cree un cliente correctamente (sin error)
            
            clienteACrear.tipclie = tipoEmpresa;
            Assert.DoesNotThrow(delegate
            {
                clienteCreado = clienteDAO.Crear(clienteACrear);
            });
            // 3. Validar que el cliente creado no sea nulo, tenga un código mayor a 0 y el tipo de empresa sea el ingresado
            Assert.IsNotNull(clienteCreado);
            Assert.Greater(clienteCreado.codclie, 0);
            Assert.AreEqual(clienteCreado.tipclie.Codigo, tipoEmpresa.Codigo);
        }
        [Test]
        public void Test2_Obtener()
        {
            Cliente clienteObtenido = null;
            // 1. Validar que se retorne nulo al obtener un cliente inexistente
            Assert.DoesNotThrow(delegate
            {
                clienteObtenido = clienteDAO.Obtener(1000);
            });
            Assert.IsNull(clienteObtenido);
            // 2. Validar que se obtenga el cliente creado satisfactoriamente
            Assert.DoesNotThrow(delegate
            {
                clienteObtenido = clienteDAO.Obtener(clienteCreado.codclie);
            });
            Assert.IsNotNull(clienteObtenido);
            // 3. Validar que el ruc obtenido sea el creado anteriormente
            Assert.AreEqual(clienteObtenido.rucclie, "12345678901");
        }
        [Test]
        public void Test3_Modificar()
        {
            Cliente clienteAModificar = clienteDAO.Obtener(clienteCreado.codclie);
            clienteAModificar.razclie = "PeruBank***";
            clienteAModificar.nroempl = 200;
            clienteAModificar.tipclie = null;
            Cliente clienteModificado = null;
            // 1. Validar que ocurrar un error al intentar modificar el cliente con un tipo de empresa nulo
            Assert.Catch<Exception>(delegate
            {
                clienteModificado = clienteDAO.Modificar(clienteAModificar);
            });
            // 2. Validar que se modifique correctamente el cliente
            clienteAModificar.tipclie = tipoEmpresa;
            Assert.DoesNotThrow(delegate
            {
                clienteModificado = clienteDAO.Modificar(clienteAModificar);
            });
            // 3. Validar que el cliente modificado no sea nulo, tenga la razón social, número de empleados y tipo indicados
            Assert.IsNotNull(clienteModificado);
            Assert.AreEqual(clienteAModificar.razclie , clienteModificado.razclie);
            Assert.AreEqual(clienteAModificar.nroempl, clienteModificado.nroempl);
            Assert.AreEqual(clienteAModificar.tipclie.Codigo, clienteModificado.tipclie.Codigo);
        }
        [Test]
        public void Test4_Eliminar()
        {
            Cliente clienteAEliminar = clienteDAO.Obtener(clienteCreado.codclie);
            // 1. Validar que ocurre un error si se intenta eliminar un cliente nulo
            Assert.Catch<Exception>(delegate
            {
                clienteDAO.Eliminar(null);
            });
            // 2. Validar que se elimina correctamente el cliente creado
            Assert.DoesNotThrow(delegate
            {
                clienteDAO.Eliminar(clienteAEliminar);
            });
            // 3. Validar que luego de eliminado se retorne nulo al obtenerlo
            Cliente clienteEliminado = clienteDAO.Obtener(clienteCreado.codclie);
            Assert.IsNull(clienteEliminado);
            
        }
        [Test]
        public void Test5_Listar()
        {
            clienteDAO.Crear(new Cliente() { rucclie = "A", razclie = "A", fecini = DateTime.Now, tipclie = tipoEmpresaDAO.Obtener(1), nroempl = 10 });
            clienteDAO.Crear(new Cliente() { rucclie = "B", razclie = "B", fecini = DateTime.Now, tipclie = tipoEmpresaDAO.Obtener(1), nroempl = 20 });
            // 1. Validar que se listen los clientes existentes exitosamente
            ICollection<Cliente> clientesExistentes = null;
            Assert.DoesNotThrow(delegate
            {
                clientesExistentes = clienteDAO.ListarTodos();
            });
            // 2. Validar que se retornen al menos los 2 clientes creados previamente
            Assert.GreaterOrEqual(clientesExistentes.Count, 2);
            // 3. Validar que cada cliente obtenido tenga un RUC no nulo
            foreach (Cliente cliente in clientesExistentes)
                Assert.IsNotNull(cliente.rucclie);
        }

 /*
        [Test]
        public void Test2_ObtenerPorRuc()
        {
            Cliente clienteObtenido = null;
            // 1. Validar que se retorne nulo al obtener un cliente inexistente
            Assert.DoesNotThrow(delegate
            {
                clienteObtenido = clienteDAO.Obtener(1000);
            });
            Assert.IsNull(clienteObtenido);
            // 2. Validar que se obtenga el cliente creado satisfactoriamente
            Assert.DoesNotThrow(delegate
            {
                clienteObtenido = clienteDAO.Obtener(clienteCreado.codclie);
            });
            Assert.IsNotNull(clienteObtenido);
            // 3. Validar que el ruc obtenido sea el creado anteriormente
            Assert.AreEqual(clienteObtenido.rucclie, "12345678901");
        }


        */



        /* [TestFixtureTearDown]
        public void FinalizarPruebas()
        {
            foreach (Cliente cliente in clienteDAO.ListarTodos())
                clienteDAO.Eliminar(cliente);
            tipoEmpresaDAO.Eliminar(tipoEmpresa);
            Persistencia.NH.NHibernateHelper.CerrarFabrica();
        }       
        */
    }
}